#include "app_buffer.h"

static pthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER;

//初始化缓冲区
Buffer *app_buffer_init(int size){
    if (size <= 0){
        log_error("buffer size error");
        return NULL;
    }
    Buffer *buffer = (Buffer *)malloc(sizeof(Buffer));
    if (buffer == NULL){
        log_error("malloc buffer error");
        return NULL;
    }

    buffer->data = (char *)malloc(size);
    if (buffer->data == NULL){
        log_error("malloc buffer data error");
        free(buffer);
        return NULL;
    }

    buffer->len = 0;
    buffer->total_size = size;
    buffer->offset = 0;

    log_debug("buffer init success");

    return buffer;

}

//释放缓冲区
void app_buffer_free(Buffer *buffer){
    if (buffer == NULL){
        return;
    }
    if (buffer->data != NULL){
        free(buffer->data);
        buffer->data = NULL;
    }
    free(buffer);
    log_debug("buffer free success");
}
//向缓冲区写入数据
int app_buffer_write(Buffer *buffer, char *data, int len){
    if (buffer == NULL || data == NULL || len <= 0){
        log_error("buffer write error");
        return -1;
    }
    if (len > buffer->total_size - buffer->len){
        log_error("buffer is full");
        return -1;
    }
    
    pthread_mutex_lock(&init_lock);
    
    int write_start = buffer->offset + buffer->len;
    if (write_start > buffer->total_size - 1){
        write_start = write_start - buffer->total_size;
    }

    if (write_start + len > buffer->total_size){
        //两段写入
        int len1 = buffer->total_size - write_start;
        memcpy(buffer->data + write_start, data, len1);
        memcpy(buffer->data, data + len1, len - len1);
    }else{
        //一段写入
        memcpy(buffer->data + write_start, data, len);
    }

    buffer->len += len;

    pthread_mutex_unlock(&init_lock);
    log_debug("buffer write success len:%d offset:%d data:%s", buffer->len, buffer->offset, buffer->data);
    return 0;
}
//读取缓冲区数据
int app_buffer_read(Buffer *buffer, char *rxbuffer, int len){
    if (buffer == NULL || rxbuffer == NULL || len <= 0){
        log_error("buffer read error");
        return -1;
    }

    if (len > buffer->len){
        log_error("buffer is not enough");
        return -1;
    }

    pthread_mutex_lock(&init_lock);

    if (buffer->offset + len > buffer->total_size){
        //两段读取
        int len1 = buffer->total_size - buffer->offset;
        memcpy(rxbuffer, buffer->data + buffer->offset, len1);
        memcpy(rxbuffer + len1, buffer->data, len - len1);
        buffer->offset = len - len1;
    }else{
        //一段读取
        memcpy(rxbuffer, buffer->data + buffer->offset, len);
        buffer->offset += len;

    }

    buffer->len -= len;
    pthread_mutex_unlock(&init_lock);
    log_debug("buffer read success len:%d offset:%d data:%s", buffer->len, buffer->offset, buffer->data);

    return 0;

}